/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package presentation.view;

import com.itextpdf.text.DocumentException;
import java.awt.Color;
import java.awt.Component;
import java.awt.Toolkit;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import presentation.controller.ControlPanelCreateSchedule;
import presentation.controller.ControlPanelMyAccount;
import presentation.controller.SchedulePanelControl;
import vo.*;

/**
 *
 * @author Joanna 8a
 */
public class PanelCreateSchedule extends javax.swing.JPanel implements Subject {

    public static final int CREATE_SCHEDULE = 1;
    public static final int UPDATE_SCHEDULE = 2;
    public static final int DELETE_SCHEDULE = 3;
    public static final int VIEW_SHCEDULE = 4;
    private List<Observer> observers;

    /**
     * Creates new form PanelCreateSchedule
     */
    public PanelCreateSchedule(AuxiliarFrame parent, JPanel predecesor, List<SubjectVO> subjects, int option) {
        initComponents();
        this.parent = parent;
        this.predecesor = predecesor;
        observers = new ArrayList<>();
        attach(MainPanel.getInstance());
        switch (option) {

            case CREATE_SCHEDULE:
                jButtonOK.setVisible(false);
                jButtonCreateSchedule.setVisible(true);
                parent.setIconImage(new javax.swing.ImageIcon(getClass().getResource("/presentation/view/images/Document.png")).getImage());
                jButtonCreateSchedule.setText("Crear Horario");
                jButtonBack.setVisible(true);
                for (SubjectVO sub : subjects) {
                    this.subjects.add(sub);
                }
                break;

            case UPDATE_SCHEDULE:
                jButtonOK.setVisible(false);
                jButtonCreateSchedule.setVisible(true);
                parent.setIconImage(new javax.swing.ImageIcon(getClass().getResource("/presentation/view/images/Table.png")).getImage());
                jButtonCreateSchedule.setText("Modificar Horario");
                jButtonBack.setVisible(true);
                for (SubjectVO sub : subjects) {
                    this.subjects.add(sub);
                }
                break;

            case VIEW_SHCEDULE:
                StudentVO active = new ControlPanelMyAccount().findByIp();
                CalendarVO calendar = new ControlPanelCreateSchedule().findCalendar(active.getCalendarId());
                subjects = calendar.getSchedule();
                for (SubjectVO sub : subjects) {
                    this.subjects.add(sub);
                }
                parent.setIconImage(new javax.swing.ImageIcon(getClass().getResource("/presentation/view/images/Calendar.png")).getImage());
                jButtonCreateSchedule.setVisible(false);
                jButtonBack.setVisible(false);
                jButtonOK.setVisible(true);
                break;

            case DELETE_SCHEDULE:
                StudentVO active2 = new ControlPanelMyAccount().findByIp();
                subjects = new ControlPanelCreateSchedule().findCalendar(active2.getCalendarId()).getSchedule();
                for (SubjectVO sub : subjects) {
                    this.subjects.add(sub);
                }
                parent.setIconImage(new javax.swing.ImageIcon(getClass().getResource("/presentation/view/images/Document New.png")).getImage());
                jButtonCreateSchedule.setVisible(true);
                jButtonCreateSchedule.setText("Eliminar Horario");
                jButtonBack.setVisible(false);
                jButtonOK.setVisible(true);
                jButtonOK.setText("Cancelar");
                break;
        }
        DefaultTableModel mod = (DefaultTableModel) jTableCreateSchedule.getModel();
        boolean valid = true;
        boolean[][] overlap = new boolean[15][8];
        TableRender tableRender = new TableRender(overlap);
        jTableCreateSchedule.setDefaultRenderer(Object.class, tableRender);
        for (SubjectVO subject : subjects) {
            for (GroupVO group : subject.getGroups()) {
                for (ClassDayVO day : group.getClassDays()) {
                    switch (day.getDay()) {
                        case "Lunes":
                            valid = fillColumn(mod, day, subject, valid, 2, overlap);
                            break;
                        case "Martes":
                            valid = fillColumn(mod, day, subject, valid, 3, overlap);
                            break;
                        case "Miercoles":
                            valid = fillColumn(mod, day, subject, valid, 4, overlap);
                            break;
                        case "Jueves":
                            valid = fillColumn(mod, day, subject, valid, 5, overlap);
                            break;
                        case "Viernes":
                            valid = fillColumn(mod, day, subject, valid, 6, overlap);
                            break;
                        case "Sabado":
                            valid = fillColumn(mod, day, subject, valid, 7, overlap);
                            break;
                        case "Domingo":
                            valid = fillColumn(mod, day, subject, valid, 1, overlap);
                            break;
                    }
                }
            }
        }
        tableRender.setOverlap(overlap);
        jTableCreateSchedule.repaint();
        if (!valid) {
            JOptionPane.showMessageDialog(this, "Los horarios de algunas materias se solapan, vuelva y corrijalo para poder crear el horario", "Aviso", JOptionPane.INFORMATION_MESSAGE);
            jButtonCreateSchedule.setEnabled(valid);
            jButtonScheduleReport.setEnabled(valid);
        }
    }

    private boolean fillColumn(DefaultTableModel mod, ClassDayVO day, SubjectVO subject, boolean valid, int column, boolean[][] overlap) {
        int subjectCode = subject.getCode()/100;        
        int group = subject.getGroups().get(0).getGroupNumber();
        
        if (mod.getValueAt((int) day.getHour() - 7, column) == null) {
            mod.setValueAt(subjectCode + "-" + group + " \n" + subject.getName(), (int) day.getHour() - 7, column);
            for (int i = 1; i < day.getSpan(); i++) {
                if (mod.getValueAt((int) day.getHour() - 7 + i, column) == null) {
                    mod.setValueAt(subjectCode + "-" + group + " \n" + subject.getName(), (int) day.getHour() - 7 + i, column);
                } else {
                    mod.setValueAt(mod.getValueAt((int) day.getHour() - 7 + i, column) + "\n/" + subjectCode + "-" + group + " \n" + subject.getName(), (int) day.getHour() - 7 + i, column);
                    valid = false;
                    overlap[(int) day.getHour() - 7 + i][column] = true;
                }
            }
        } else {
            mod.setValueAt(mod.getValueAt((int) day.getHour() - 7, column) + "\n/" + subjectCode + "-" + group + " \n" + subject.getName(), (int) day.getHour() - 7, column);
            valid = false;
            overlap[(int) day.getHour() - 7][column] = true;
            for (int i = 1; i < day.getSpan(); i++) {
                if (mod.getValueAt((int) day.getHour() - 7 + i, column) == null) {
                    mod.setValueAt(subjectCode + "-" + group + " \n" + subject.getName(), (int) day.getHour() - 7 + i, column);
                } else {
                    mod.setValueAt(mod.getValueAt((int) day.getHour() - 7 + i, column) + "\n/" + subjectCode + "-" + group + " \n" + subject.getName(), (int) day.getHour() - 7 + i, column);
                    valid = false;
                    overlap[(int) day.getHour() - 7 + i][column] = true;
                }
            }
        }
        packColumn(jTableCreateSchedule, column, 2);
        return valid;
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPaneCreateSchedule = new javax.swing.JScrollPane();
        jTableCreateSchedule = new javax.swing.JTable();
        jButtonCreateSchedule = new javax.swing.JButton();
        jButtonBack = new javax.swing.JButton();
        jButtonOK = new javax.swing.JButton();
        jButtonScheduleReport = new javax.swing.JButton();

        setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Crear Horario", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Segoe UI Light", 1, 14), new java.awt.Color(102, 0, 102))); // NOI18N

        jTableCreateSchedule.setFont(new java.awt.Font("Segoe UI Light", 0, 14)); // NOI18N
        jTableCreateSchedule.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {"7:00", null, null, null, null, null, null, null},
                {"8:00", null, null, null, null, null, null, null},
                {"9:00", null, null, null, null, null, null, null},
                {"10:00", null, null, null, null, null, null, null},
                {"11.00", null, null, null, null, null, null, null},
                {"12:00", null, null, null, null, null, null, null},
                {"13:00", null, null, null, null, null, null, null},
                {"14:00", null, null, null, null, null, null, null},
                {"15:00", null, null, null, null, null, null, null},
                {"16:00", null, null, null, null, null, null, null},
                {"17:00", null, null, null, null, null, null, null},
                {"18:00", null, null, null, null, null, null, null},
                {"19:00", null, null, null, null, null, null, null},
                {"20:00", null, null, null, null, null, null, null},
                {"21:00", null, null, null, null, null, null, null}
            },
            new String [] {
                "Hora", "Domingo", "Lunes", "Martes", "Miercoles", "Jueves", "Viernes", "Sábado"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class
            };
            boolean[] canEdit = new boolean [] {
                false, false, false, false, false, false, false, false
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        jScrollPaneCreateSchedule.setViewportView(jTableCreateSchedule);
        jTableCreateSchedule.getColumnModel().getColumn(0).setPreferredWidth(70);

        jButtonCreateSchedule.setFont(new java.awt.Font("Segoe UI Light", 0, 14)); // NOI18N
        jButtonCreateSchedule.setIcon(new javax.swing.ImageIcon(getClass().getResource("/presentation/view/images/Table.png"))); // NOI18N
        jButtonCreateSchedule.setText("Crear Horario");
        jButtonCreateSchedule.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonCreateScheduleActionPerformed(evt);
            }
        });

        jButtonBack.setFont(new java.awt.Font("Segoe UI Light", 0, 14)); // NOI18N
        jButtonBack.setIcon(new javax.swing.ImageIcon(getClass().getResource("/presentation/view/images/Back.png"))); // NOI18N
        jButtonBack.setText("Volver");
        jButtonBack.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonBackActionPerformed(evt);
            }
        });

        jButtonOK.setFont(new java.awt.Font("Segoe UI Light", 0, 14)); // NOI18N
        jButtonOK.setText("OK");
        jButtonOK.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonOKActionPerformed(evt);
            }
        });

        jButtonScheduleReport.setFont(new java.awt.Font("Segoe UI Light", 0, 14)); // NOI18N
        jButtonScheduleReport.setIcon(new javax.swing.ImageIcon(getClass().getResource("/presentation/view/images/Document2.png"))); // NOI18N
        jButtonScheduleReport.setText("Imprimir");
        jButtonScheduleReport.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonScheduleReportActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jButtonScheduleReport)
                .addGap(270, 270, 270)
                .addComponent(jButtonBack)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(jButtonCreateSchedule)
                .addGap(87, 87, 87)
                .addComponent(jButtonOK)
                .addGap(37, 37, 37))
            .addComponent(jScrollPaneCreateSchedule)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(26, 26, 26)
                .addComponent(jScrollPaneCreateSchedule, javax.swing.GroupLayout.DEFAULT_SIZE, 288, Short.MAX_VALUE)
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButtonOK)
                    .addComponent(jButtonCreateSchedule)
                    .addComponent(jButtonBack)
                    .addComponent(jButtonScheduleReport))
                .addContainerGap())
        );
    }// </editor-fold>//GEN-END:initComponents

    private void jButtonCreateScheduleActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonCreateScheduleActionPerformed
        switch (jButtonCreateSchedule.getText()) {
            case "Crear Horario":
                if (subjects.size() > 0) {
                    new ControlPanelCreateSchedule().deleteSchedule(subjects.get(0).getCalendarId());
                }
                if (new ControlPanelCreateSchedule().createSchedule(subjects)) {
                    new ControlPanelCreateSchedule().createProjectsFromSubjects(subjects);
                    notifyObserver();
                    JOptionPane.showMessageDialog(this, "Horario creado correctamente!", "Aviso", JOptionPane.INFORMATION_MESSAGE);
                    parent.dispose();
                } else {
                    JOptionPane.showMessageDialog(this, "El Horario no se ha podido crear", "Error", JOptionPane.ERROR_MESSAGE);
                }
                break;

            case "Modificar Horario":
                if (subjects.size() > 0) {
                    new ControlPanelCreateSchedule().deleteSchedule(subjects.get(0).getCalendarId());
                }
                if (new ControlPanelCreateSchedule().createSchedule(subjects)) {
                    new ControlPanelCreateSchedule().createProjectsFromSubjects(subjects);
                    notifyObserver();
                    JOptionPane.showMessageDialog(this, "Horario modificado correctamente!", "Aviso", JOptionPane.INFORMATION_MESSAGE);
                    parent.dispose();
                } else {
                    JOptionPane.showMessageDialog(this, "El Horario no se ha podido modificar", "Error", JOptionPane.ERROR_MESSAGE);
                }
                break;

            case "Eliminar Horario":
                if (new ControlPanelCreateSchedule().deleteSchedule(subjects.get(0).getCalendarId())) {
                    JOptionPane.showMessageDialog(this, "Horario eliminado correctamente!", "Aviso", JOptionPane.INFORMATION_MESSAGE);
                    parent.dispose();
                } else {
                    JOptionPane.showMessageDialog(this, "El Horario no se ha podido eliminar", "Error", JOptionPane.ERROR_MESSAGE);
                }
                break;
        }
    }//GEN-LAST:event_jButtonCreateScheduleActionPerformed

    private void jButtonBackActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonBackActionPerformed
        parent.cambiarPanel(predecesor);
    }//GEN-LAST:event_jButtonBackActionPerformed

    private void jButtonOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonOKActionPerformed
        parent.dispose();
    }//GEN-LAST:event_jButtonOKActionPerformed

    private void jButtonScheduleReportActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonScheduleReportActionPerformed
        try {
            new SchedulePanelControl().generateScheduleReport(this, jTableCreateSchedule);
        } catch (DocumentException ex) {
            Logger.getLogger(PanelCreateSchedule.class.getName()).log(Level.SEVERE, null, ex);
        } catch (FileNotFoundException ex) {
            Logger.getLogger(PanelCreateSchedule.class.getName()).log(Level.SEVERE, null, ex);
        }
    }//GEN-LAST:event_jButtonScheduleReportActionPerformed
    private final List<SubjectVO> subjects = new ArrayList<>();
    private AuxiliarFrame parent;
    private JPanel predecesor;
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButtonBack;
    private javax.swing.JButton jButtonCreateSchedule;
    private javax.swing.JButton jButtonOK;
    private javax.swing.JButton jButtonScheduleReport;
    private javax.swing.JScrollPane jScrollPaneCreateSchedule;
    private javax.swing.JTable jTableCreateSchedule;
    // End of variables declaration//GEN-END:variables

    @Override
    public void attach(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void notifyObserver() {
        for (Observer observer : observers) {
            observer.update();
        }
    }

    @Override
    public void remove(Observer observer) {
        observers.remove(observer);
    }

    class TableRender extends JLabel implements TableCellRenderer {

        private boolean[][] overlap;

        public boolean[][] getOverlap() {
            return overlap;
        }

        public void setOverlap(boolean[][] overlap) {
            this.overlap = overlap.clone();
        }

        public TableRender(boolean[][] overlap) {
            this.overlap = overlap.clone();
        }

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            JTextArea text = new JTextArea();
            if (overlap[row][column]) {
                text.setBackground(Color.RED);
                text.setForeground(Color.WHITE);
                table.setRowHeight(row, 100);
            } else if (column == 0) {
                text.setBackground(Color.LIGHT_GRAY);
            } else if (value != null) {
                text.setBackground(Color.BLUE);
                text.setForeground(Color.WHITE);
                if (table.getRowHeight(row) < 50) {
                    table.setRowHeight(row, 50);
                }
            }
            if (value instanceof String || value instanceof SubjectVO) {
                text.setOpaque(true);
                text.setText(value.toString());
            }
            return text;
        }
    }

    public void packColumn(JTable table, int vColIndex, int margin) {
        DefaultTableColumnModel colModel = (DefaultTableColumnModel) table.getColumnModel();
        TableColumn col = colModel.getColumn(vColIndex);
        int width = 0;
        TableCellRenderer renderer = col.getHeaderRenderer();
        if (renderer == null) {
            renderer = table.getTableHeader().getDefaultRenderer();
        }
        Component comp = renderer.getTableCellRendererComponent(
                table, col.getHeaderValue(), false, false, 0, 0);
        width = comp.getPreferredSize().width;
        for (int r = 0; r < table.getRowCount(); r++) {
            renderer = table.getCellRenderer(r, vColIndex);
            comp = renderer.getTableCellRendererComponent(
                    table, table.getValueAt(r, vColIndex), false, false, r, vColIndex);
            width = Math.max(width, comp.getPreferredSize().width);
        }
        width += 2 * margin;
        col.setPreferredWidth(width);
    }
}
